﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using AmuTools;
using app.Api;

namespace app.Models
{
    /*
        自由值

        Set 可以设置任意变量，在存到数据库的同时，会存到内存中。
        Get 树形结构保证当我们要拿到值的时候速度快，不需要到数据库中查询
        GetValue 返回字符串
    */

    [Model(TableName = "t_free_value", PrimaryKey = "id", IdentityInsert = true)]
    public class FreeValue
    {
        #region 字段
        [Field(Description = "自由变量标识")]
        public int id { get; set; }
        [Field( Description = "父亲节点id")]
        public int parent_id { get; set; }

        [Field(FieldName = "_key")]
        public string key { get; set; }

        [Field(DataType = "varchar(MAX)")]
        public string value { get; set; }
        [Field(DataType = "char(13)")]
        public string create_time { get; set; }
        #endregion

        #region 自由值缓存机制
        private static Dictionary<string, object> cache = null;

        public static string GetValue(string the_key, object default_value = null)
        {
            Dictionary<string, object> result = Get(the_key);
            if (result == null || result["value"] == null)
            {
                return default_value.ToString();
            }
            else return result["value"].ToString();
        }

        public static Dictionary<string, object> Get(string the_keys)
        {
            string[] keys = the_keys.Split('.');
            GetCache();
            Dictionary<string, object> temp = cache;
            int i = 0;
            for (int len = keys.Length; i < len; i++)
            {
                if (temp.ContainsKey(keys[i]))
                {
                    if (temp[keys[i]] is Dictionary<string, object>) temp = (Dictionary<string, object>)temp[keys[i]];
                    else return null;
                }
                else return null;
            }
            return temp;
        }
        //public static Dictionary<string, object> Delete(string the_keys)
        //{
        //    string[] keys = the_keys.Split('.');
        //    GetCache();
        //    Dictionary<string, object> temp = cache;
        //    int i = 0;
        //    for (int len = keys.Length; i < len; i++)
        //    {
        //        if (temp.ContainsKey(keys[i]))
        //        {
        //            if (temp[keys[i]] is Dictionary<string, object>)
        //            {
        //                temp = (Dictionary<string, object>)temp[keys[i]];                                     
        //                G.DB.DeleteByCondition<FreeValue>(id == (int)temp["id"]|| parent_id == (int)temp["id"]);  
                       

        //            }
        //            else return null;
        //        }
        //        else return null;
        //    }
        //    return temp;
        //}

        // 设置系统变量
        public static void Set(string the_keys, object the_value)
        {
            string[] keys = the_keys.Split('.'); // the_keys内容例如：website.phone,则keys为["website", "phone"]
            // 获取缓存，如果存在则不会二次请求数据库
            GetCache();
            Dictionary<string, object> temp = cache; // 先让temp为缓存根
            // 循环检测，例如检测有没有website，没有就创建一个，再检测有没有phone，没有则再创建，直到keys的最后一个值
            for (int i = 0, len = keys.Length; i < len; i++)
            {
                // 首先检测属性名是否为数据库字段，如果为数据库字段则冲突，抛出异常
                string key = keys[i];
                if (key == "id" || key == "parent_id" || key == "value") throw new Exception("属性名不能为id、parent_id、value");
                // 检测是否已经存在对应值，如果不存在，创建
                if (!temp.ContainsKey(key))
                {
                    // 先在数据库中插入要创建的内容
                    FreeValue fv = new FreeValue { parent_id = (int)temp["id"], key = key };
                    G.DB.Insert<FreeValue>(fv);
                    // 然后将新的内容添加到缓存树中
                    Dictionary<string, object> fv_dic = new Dictionary<string, object>();
                    fv_dic.Add("value", fv.value);
                    fv_dic.Add("id", fv.id);
                    fv_dic.Add("parent_id", fv.parent_id);
                    temp.Add(key, fv_dic);
                }
                temp = (Dictionary<string, object>)temp[key];
            }
            // 这时候拿到了keys的最后一个值，设置值，同步数据库
            FreeValue fv2 = G.DB.GetById<FreeValue>(temp["id"].ToString());
            fv2.value = the_value.ToString();
            temp["value"] = the_value;
            G.DB.Update<FreeValue>(fv2);
        }

        public static Dictionary<string, object> GetCache()
        {
            if (cache != null)
            {
                return cache;
            }

            List<FreeValue> list = G.DB.Get<FreeValue>().GetFirstTableList();
            Dictionary<int, Dictionary<string, object>> dic = new Dictionary<int, Dictionary<string, object>>();
            Dictionary<string, object> root = new Dictionary<string, object>();
            root.Add("id", 0);
            root.Add("parent_id", 0);
            root.Add("root", root);
            root.Add("key", "root");
            dic.Add(0, root);
            // 首先构造一个id的map字典，方便根据id查找
            foreach (FreeValue fv in list)
            {
                Dictionary<string, object> temp1 = new Dictionary<string, object>();
                Dictionary<string, object> temp2 = new Dictionary<string, object>();
                temp2.Add("value", fv.value);
                temp2.Add("id", fv.id);
                temp2.Add("parent_id", fv.parent_id);
                temp1.Add(fv.key, temp2);
                temp1.Add("key", fv.key);
                dic.Add(fv.id, temp1);
            }
            // 开始构建关系
            foreach (FreeValue fv in list)
            {
                Dictionary<string, object> target = dic[fv.parent_id];
                Dictionary<string, object> self = dic[fv.id];
                ((Dictionary<string, object>)target[target["key"].ToString()]).Add(fv.key, self[fv.key]);
            }
            // 得到root内容
            cache = (Dictionary<string, object>)dic[0]["root"];

            return cache;
        }
        #endregion

        #region 初始值设置
        public static FreeValue[] GetInitData()
        {
            // 网站基本信息
            Set("website.name", "秦皇岛市金融办");
            Set("website.phone", "68478327489");
            Set("website.zip_code", "066300");
            Set("website.email", "xx@xx.com");
            Set("website.tecnicaladdress", "http://www.wantongsoft.com/"); // 技术支持：万通官网
            Set("website.is_maintain", "0"); // 系统是否正在维护
            Set("website.maintain_reason", "系统升级中"); // 系统维护原因
            Set("website.view_timer", "1523123111111"); // 系统维护原因
            Set("website.page_view", "0"); // 系统维护原因
            Set("website.page_view_today", "0"); // 系统维护原因
            // 手机发送短信相关
            Set("phone.phone1.phone_id", "1");
            Set("phone.phone1.username", "wantong1");
            Set("phone.phone1.password", "wtruanjian");

            //dh发送邮件相关
            Set("email.email1.email_id", "1");
            Set("email.email1.email_name", "xx@xx.com");
            Set("email.email1.eu_password", "wtruanjian");
            Set("email.email1.email_password", "wtruanjian");
            Set("email.email1.email_smtp", "wtruanjian");
            Set("email.email1.email_port", "wtruanjian");
            return new FreeValue[] { };
        }
        #endregion
    }
}



//public static string Get(string the_keys)
//{
//    string[] keys = the_keys.Split('.');
//    GetCache();
//    FreeValue temp = new FreeValue();
//    int id = 0;
//    for (int i = 0, len = keys.Length; i < len; i++)
//    {
//        temp = cache.Where(r => r.parent_id == id && r.key == keys[i]).FirstOrDefault();
//        if (temp == null)
//        {
//            return null;
//        }
//        id = temp.id;
//    }
//    return temp.value;
//}

//public static void Set(string the_keys, string the_value, bool update = true)
//{
//    string[] keys = the_keys.Split('.');
//    GetCache();
//    FreeValue temp = new FreeValue();
//    int id = 0;
//    for (int i = 0, len = keys.Length; i < len; i++)
//    {
//        Cd cd = new Cd();
//        cd.And("parent_id={0}", id);
//        cd.And("key='{0}'", keys[i]);
//        temp = G.DB.Get<FreeValue>(cd.Render()).GetFirstEntity();
//        if (temp == null)
//        {
//            FreeValue fv = new FreeValue { parent_id = id, key = keys[i] };
//            G.DB.Insert<FreeValue>(fv);
//            temp = fv;
//        }
//        id = temp.id;
//    }
//    temp.value = the_value;

//    if (update)
//    {
//        cache = null;
//        GetCache();
//    }
//}